package com.wolfcode.business.service.impl;

import java.math.BigDecimal;
import java.util.List;

import com.wolfcode.business.domain.qo.ContractQo;
import com.wolfcode.business.domain.vo.ContractVo;
import com.wolfcode.business.enums.ContractAuditEnum;
import com.wolfcode.business.enums.ContractNullifyEnum;
import com.wolfcode.business.enums.ContractSealEnum;
import com.wolfcode.common.utils.DateUtils;
import com.wolfcode.common.utils.FileUpLoadUtils;
import com.wolfcode.common.utils.SecurityUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.wolfcode.business.mapper.ContractMapper;
import com.wolfcode.business.domain.Contract;
import com.wolfcode.business.service.IContractService;
import org.springframework.util.Assert;

/**
 * 合同信息Service业务层处理
 *
 * @author wolfcode
 * @date 2022-12-10
 */
@Service
public class ContractServiceImpl implements IContractService {
    @Autowired
    private ContractMapper contractMapper;

    /**
     * 查询合同信息
     *
     * @param id 合同信息主键
     * @return 合同信息
     */
    @Override
    public Contract selectContractById(Long id) {
        return contractMapper.selectContractById(id);
    }

    /**
     * 查询合同信息列表
     *
     * @param contractQo 合同信息
     * @return 合同信息
     */
    @Override
    public List<Contract> selectContractList(ContractQo contractQo) {
        return contractMapper.selectContractList(contractQo);
    }

    /**
     * 新增合同信息
     *
     * @param contractVo 合同信息
     * @return 结果
     */
    @Override
    public int insertContract(ContractVo contractVo) throws Exception {
        // 数据校验
        Assert.notNull(contractVo, "非法参数");
        Assert.notNull(contractVo.getCustomerId(), "客户选择不能为空");
        Assert.state(contractVo.getContractName().length() < 100, "合同名称字数必须在100以内");
        Assert.state(contractVo.getContractCode().length() < 50, "合同编码字数必须在50以内");
        Assert.state(contractVo.getAmounts().compareTo(new BigDecimal("0")) > 0, "合同金额必须大于0");
        Assert.state(contractVo.getStartDate().compareTo(contractVo.getEndDate()) <= 0, "合同有效结束日期必须大于开始日期");

        //
        String fileAddress = FileUpLoadUtils.getFileAddress(contractVo.getAppendix());
        Contract contract = new Contract();
        BeanUtils.copyProperties(contractVo, contract);
        // 设置审核状态初始化
        contract.setAuditState(ContractAuditEnum.Unapproved.ordinal());
        // 设置盖章状态为否
        contract.setAffixSealState(ContractSealEnum.NO.ordinal());
        // 设置使用状态为在用
        contract.setNullifyState(ContractNullifyEnum.USING.ordinal());
        // 设置录入人
        contract.setInputUser(SecurityUtils.getUserId());
        // 设置录入时间
        contract.setInputTime(DateUtils.getNowDate());
        // 设置文件路径
        contract.setAppendix(fileAddress);
        return contractMapper.insertContract(contract);
    }

    /**
     * 修改合同信息
     *
     * @param contractVo 合同信息
     * @return 结果
     */
    @Override
    public int updateContract(ContractVo contractVo) throws Exception {
        // 数据校验
        Assert.notNull(contractVo, "非法参数");
        Assert.state(contractVo.getContractName().length() < 100, "合同名称字数必须在100以内");
        Assert.state(contractVo.getContractCode().length() < 50, "合同编码字数必须在50以内");
        Assert.state(contractVo.getAmounts().compareTo(new BigDecimal("0")) > 0, "合同金额必须大于0");
        Assert.state(contractVo.getStartDate().compareTo(contractVo.getEndDate()) <= 0, "合同有效结束日期必须大于开始日期");



        Contract contract = contractMapper.selectContractById(contractVo.getId());
        Assert.notNull(contract, "数据错误");
        // 只有未审核或审核不通过的合同才可以修改
        Assert.state(contract.getAuditState() == ContractAuditEnum.Unapproved.ordinal()
                        || contract.getAuditState() == ContractAuditEnum.REJECT.ordinal(),
                "只有未审核或审核不通过的合同才可以修改");
        // 作废的合同不能进行任何其他操作
        Assert.state(contract.getNullifyState() != ContractNullifyEnum.CANCEL.ordinal(), "作废的合同不能进行任何其他操作");
        // TODO 电子附件功能未完成
        Contract updateContract = new Contract();
        BeanUtils.copyProperties(contractVo, updateContract);
        // 设置审核状态为待审核
        updateContract.setAuditState(ContractAuditEnum.Unapproved.ordinal());
        if (contractVo.getAppendix() != null) {
            String fileAddress = FileUpLoadUtils.getFileAddress(contractVo.getAppendix());
            // 设置文件路径
            updateContract.setAppendix(fileAddress);
        }
        return contractMapper.updateContract(updateContract);
    }

    /**
     * 批量删除合同信息
     *
     * @param ids 需要删除的合同信息主键
     * @return 结果
     */
    @Override
    public int deleteContractByIds(Long[] ids) {
        return contractMapper.deleteContractByIds(ids);
    }

    /**
     * 删除合同信息信息
     *
     * @param id 合同信息主键
     * @return 结果
     */
    @Override
    public int deleteContractById(Long id) {
        return contractMapper.deleteContractById(id);
    }

    /**
     * 合同作废
     *
     * @param id 合同信息id
     */
    @Override
    public void cancelContract(Long id) {
        // 数据校验
        Assert.notNull(id, "非法参数");
        Contract contract = contractMapper.selectContractById(id);
        Assert.notNull(contract, "数据错误");
        // 已盖章的合同不能作废
        Assert.state(contract.getAffixSealState() != ContractSealEnum.YES.ordinal(),
                "已盖章的合同不能作废");
        // 设置合同使用状态为作废
        contract.setNullifyState(ContractNullifyEnum.CANCEL.ordinal());
        contractMapper.updateContract(contract);
    }

    /**
     * 审核通过
     *
     * @param id 合同信息id
     */
    @Override
    public void auditSuccess(Long id) {
        // 数据校验
        Assert.notNull(id, "非法参数");
        Contract contract = contractMapper.selectContractById(id);
        Assert.notNull(contract, "数据错误");
        // 只有待审核的合同才能进行审核操作
        Assert.state(contract.getAuditState() == ContractAuditEnum.Unapproved.ordinal(),
                "只有待审核的合同才能进行审核操作");
        // 只有未盖章的合同才能进行审核操作
        Assert.state(contract.getAffixSealState() == ContractSealEnum.NO.ordinal(),
                "只有未盖章的合同才能进行审核操作");
        // 只有未作废的合同才能进行审核操作
        Assert.state(contract.getNullifyState() != ContractNullifyEnum.CANCEL.ordinal(),
                "只有未作废的合同才能进行审核操作");
        contract.setAuditState(ContractAuditEnum.PASS.ordinal());
        contractMapper.updateContract(contract);
    }

    /**
     * 审核不通过
     *
     * @param id 合同信息id
     */
    @Override
    public void auditFail(Long id) {
        // 数据校验
        Assert.notNull(id, "非法参数");
        Contract contract = contractMapper.selectContractById(id);
        Assert.notNull(contract, "数据错误");
        // 只有待审核的合同才能进行审核操作
        Assert.state(contract.getAuditState() == ContractAuditEnum.Unapproved.ordinal(),
                "只有待审核的合同才能进行审核操作");
        // 只有未盖章的合同才能进行审核操作
        Assert.state(contract.getAffixSealState() == ContractSealEnum.NO.ordinal(),
                "只有未盖章的合同才能进行审核操作");
        // 只有未作废的合同才能进行审核操作
        Assert.state(contract.getNullifyState() != ContractNullifyEnum.CANCEL.ordinal(),
                "只有未作废的合同才能进行审核操作");
        contract.setAuditState(ContractAuditEnum.REJECT.ordinal());
        contractMapper.updateContract(contract);
    }

    @Override
    public void handleSeal(Long id) {
        // 数据校验
        Assert.notNull(id, "非法参数");
        Contract contract = contractMapper.selectContractById(id);
        Assert.notNull(contract, "数据错误");
        // 只有审核通过的合同才能盖章
        Assert.state(contract.getAuditState() == ContractAuditEnum.PASS.ordinal(),
                "只有审核通过的合同才能盖章");
        // 只有未盖章的合同才能进行盖章
        Assert.state(contract.getAffixSealState() == ContractSealEnum.NO.ordinal(),
                "只有未盖章的合同才能进行盖章");
        // 只有未作废的合同才能进行审核操作
        Assert.state(contract.getNullifyState() != ContractNullifyEnum.CANCEL.ordinal(),
                "只有未作废的合同才能进行审核操作");
        contract.setAffixSealState(ContractSealEnum.YES.ordinal());
        contractMapper.updateContract(contract);
    }
}
